//----------------------------------------------------------------------------
//  ,-.
// /_\___ ,   Ninja Framework
// '  ___\    (C) Riccardo Capra - http://riccar.do
//  //   \\
//----------------------------------------------------------------------------
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------------

#ifndef NJ_ASSERT_H
#	define NJ_ASSERT_H

#	include "NjNinjaSyncLib.h"
#	include "NjAssert_config.h"

#	if NJ_ASSERT_ENABLED
#		include "NjFundamentalMacros.h"

	/// \brief Implements assertion methods
	class NjAssert
	{
	public:
		/// \brief Triggers an assertion if \em bCondition is NJ_FALSE
		/// \param bCondition The condition that if NJ_FALSE will trigger the assertion
		/// \param szCondition The condition converted to string
		/// \param szMessage A custom message to be displayed when the assert is triggered
		/// \param szFile The C++ file that triggered the assert
		/// \param uLine The C++ file line that triggered the assert
		/// \param szFunction The C++ function/method that triggered the assert
		static void Assert(NjBool bCondition, NjCharA const * szCondition, NjCharA const * szMessage, NjCharA const * szFile, NjUint uLine, NjCharA const * szFunction);

		NJ_DISABLE_INSTANCE(NjAssert);

	private:
		/// \brief Implements the assertion trigger
		/// \param szCondition The condition converted to string
		/// \param szMessage A custom message to be displayed when the assert is triggered
		/// \param szFile The C++ file that triggered the assert
		/// \param uLine The C++ file line that triggered the assert
		/// \param szFunction The C++ function/method that triggered the assert
		static void OnAssert(NjCharA const * szCondition, NjCharA const * szMessage, NjCharA const * szFile, NjUint uLine, NjCharA const * szFunction);
	};

#		include "NjAssert_inline.h"

		/// \brief Triggers an assertion if \em bCondition is NJ_FALSE
		/// \param szCondition The condition converted to string
		/// \param szMessage A custom message to be displayed when the assert is triggered
#		define __NJ_ASSERT(bCondition, szCondition, szMessage) NjAssert::Assert(bCondition, szCondition, szMessage, __FILE__, __LINE__, __FUNCTION__)
#	else // NJ_ASSERT_ENABLED
#		define __NJ_ASSERT(bCondition, szCondition, szMessage)
#	endif // NJ_ASSERT_ENABLED

/// \brief Triggers an assertion if \em bCondition is NJ_FALSE
/// \param bCondition The condition that if NJ_FALSE will trigger the assertion
/// \param szMessage A custom message to be displayed when the assert is triggered
#	define NJ_ASSERT_MSG(bCondition, szMessage) __NJ_ASSERT(bCondition, NJ_TO_STRING8(bCondition), szMessage)

/// \brief Inconditionally triggers an assertion
/// \param szMessage A custom message to be displayed when the assert is triggered
#	define NJ_BREAK_MSG(szMessage) __NJ_ASSERT(NJ_FALSE, NJ_NULL, szMessage)

/// \brief Triggers an assertion if \em bCondition is NJ_FALSE
/// \param bCondition The condition that if NJ_FALSE will trigger the assertion
#	define NJ_ASSERT(bCondition) NJ_ASSERT_MSG(bCondition, NJ_NULL)

/// \brief Inconditionally triggers an assertion
#	define NJ_BREAK() NJ_BREAK_MSG(NJ_NULL)

#endif // NJ_ASSERT_H
